from datetime import datetime
from typing import List

from fastapi import APIRouter, Depends, Path, Request, Form
from fastapi.responses import RedirectResponse
from sqlalchemy import desc, select, func, delete

from core.database import db_session
from core.exception import AlertException
from core.models import Group, GroupMember, Member
from core.template import AdminTemplates
from lib.common import set_url_query_params
from lib.dependency.dependencies import common_search_query_params, validate_token
from lib.template_functions import get_paging

router = APIRouter()
templates = AdminTemplates()


@router.get("/boardgroupmember_list/{gr_id}")
async def boardgroupmember_list(
    request: Request,
    db: db_session,
    gr_id: str = Path(...),
    search_params: dict = Depends(common_search_query_params)
):
    """
    按组列出的访问成员列表
    """
    config = request.state.config

    sfl = search_params['sfl']
    stx = search_params['stx']
    sst = search_params['sst']
    sod = search_params['sod']
    current_page = search_params['current_page']
    records_per_page = getattr(config, "cf_page_rows", 10)

    # 集团信息
    group = db.get(Group, gr_id)
    if not group:
        raise AlertException(f"{gr_id} 组不存在.", 404)

    # 组成员列表
    query = select().where(GroupMember.gr_id == gr_id)
    # 搜索条件
    if sfl and stx:
        query = query.where(getattr(GroupMember, sfl).like(f"%{stx}%"))
    # 校准条件
    if sst:
        if sod == "desc":
            query = query.order_by(desc(getattr(GroupMember, sst)))
        else:
            query = query.order_by(getattr(GroupMember, sst))
    else:
        query = query.order_by(GroupMember.gm_id)

    # 根据页码 offset 计算
    offset = (current_page - 1) * records_per_page
    # 计算记录的总数
    total_count = db.scalar(query.add_columns(func.count(GroupMember.gm_id)).order_by(None))
    # 获取最终查询结果.
    group_members = db.scalars(
        query.add_columns(GroupMember).offset(offset).limit(records_per_page)
    ).all()

    for group_member in group_members:
        group_member.member_info = group_member.member
        group_member.group_count = len(group_member.member.groups)

    context = {
        "request": request,
        "group": group,
        "group_members": group_members,
        "total_count": total_count,
        "current_page": current_page,
        "paging": get_paging(request, current_page, total_count, records_per_page),
    }
    return templates.TemplateResponse("boardgroupmember_list.html", context)


@router.get("/boardgroupmember_form/{mb_id}")
async def board_form(
    request: Request,
    db: db_session,
    mb_id: str = Path(...)
):
    """
    成员可访问的公告板组列表
    """
    exists_member = db.scalar(select(Member).filter_by(mb_id=mb_id))
    if not exists_member:
        raise AlertException(f"{mb_id} 成员不存在.", 404)

    query_groups = select(Group).filter_by(gr_use_access = 1).order_by(Group.gr_id)
    query_allow_groups = select(Group, GroupMember).join(GroupMember).where(GroupMember.mb_id == mb_id).order_by(desc(Group.gr_id))
    # 只看你管理的组
    if not request.state.is_super_admin:
        query_groups = query_groups.filter_by(gr_admin=mb_id)
        query_allow_groups = query_allow_groups.where(Group.gr_admin == mb_id)

    groups = db.scalars(query_groups).all()
    allow_groups = db.execute(query_allow_groups).all()

    context = {
        "request": request,
        "member": exists_member,
        "groups": groups,
        "allow_groups": allow_groups,
    }
    return templates.TemplateResponse("boardgroupmember_form.html", context)


@router.post("/boardgroupmember_insert", dependencies=[Depends(validate_token)])
async def boardgroupmember_insert(
    request: Request,
    db: db_session,
    mb_id: str = Form(...),
    gr_id: str = Form(...),
):
    """
    添加可访问的组成员
    """
    exists_member = db.scalar(select(Member).filter_by(mb_id=mb_id))
    if not exists_member:
        raise AlertException(f"{mb_id} 成员不存在.", 404)

    exists_group = db.get(Group, gr_id)
    if not exists_group:
        raise AlertException(f"{gr_id} 组不存在.", 404)

    exists_group_member = db.scalar(select(GroupMember).filter_by(mb_id = mb_id, gr_id = gr_id))
    if exists_group_member:
        raise AlertException(f"{mb_id} 成员已经 {gr_id} 您已在群组中注册.", 409)

    group_member = GroupMember(
        gr_id=gr_id,
        mb_id=mb_id,
        gm_datetime=datetime.now(),
    )
    db.add(group_member)
    db.commit()

    return RedirectResponse(f"/admin/boardgroupmember_form/{mb_id}", status_code=303)


@router.post("/boardgroupmember_delete", dependencies=[Depends(validate_token)])
async def boardgroupmember_delete(
    request: Request,
    db: db_session,
    checks: List[int] = Form(None, alias="chk[]"),
    mb_id: str = Form(None),
    gr_id: str = Form(None),
):
    """
    删除可访问的组成员
    """
    db.execute(delete(GroupMember).where(GroupMember.gm_id.in_(checks)))
    db.commit()

    if mb_id:
        url = f"/admin/boardgroupmember_form/{mb_id}"
    else:
        url = f"/admin/boardgroupmember_list/{gr_id}"
    query_params = request.query_params
    return RedirectResponse(set_url_query_params(url, query_params), 303)
